package com.pfdu.simplescheduler.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;

@Data
@Component
public class SimpleSchedulerConfig {

    /**
     * 任务筛选策略
     * 《性能调优项》
     * 该项也是部署的多个应用节点执行任务的负载均衡策略
     */
    @Value("${simple-scheduler.task-filter-strategy:default}")
    private String strategy;

    /**
     * 缓冲队列，暂存加载后待执行的任务
     * 与性能关系不大
     * 设置的太大会导致大量Task超期，增加无谓的Task状态重置工作，浪费数据库服务器资源。
     */
    @Value("${simple-scheduler.task-load-queue-size:1}")
    private int queueSize;

    /**
     * 任务执行线程的数量
     * 《性能调优项》
     * 根据应用服务器的CPU核心数设置，推荐 CPU core * 2。
     */
    @Value("${simple-scheduler.task-executor-size:8}")
    private int executorSize;

    /**
     * 两次任务加载的间隔，单位毫秒
     * 《性能调优项》
     * 根据任务执行时长调节该项，如果单个任务执行耗时较长（如2秒），那么该配置项也可以相应的配置的较大一些（2秒）。
     */
    @Value("${simple-scheduler.task-load-interval:100}")
    private int loadInterval;

    /**
     * WorkerGroup没有空闲的 Worker时，Boss指派工作任务就会失败，然后尝试再次指派，直到指派成功为止。该项即为 Boss指派任务失败后的休息时间，单位毫秒。
     * 《性能调优项》
     * 应该根据单个任务的执行时长决定该项的数值大小，如果任务平均执行时长为2000ms，该值就可设置为2000或者1500或者1000。
     */
    @Value("${simple-scheduler.interval-between-boss-allot-task-while-workergroup-busy:100}")
    private int bossAllotTaskInterval;

    /**
     * 任务执行超时的时长，默认值1800，单位秒，即30分钟。
     * 与性能关系不大
     * 根据业务需要自行设置，因为应用服务器之间存在时间差，所以该值不能设置的太小。
     */
    @Value("${simple-scheduler.task-execute-out-time:1800}")
    private int taskExecuteOutTime;

    /**
     * 重置任务状态的扫描周期，默认值600000，单位毫秒，即10分钟。
     * 与性能关系不大
     * 该值的大小可根据 taskExecuteOutTime的大小做设置，比如任务执行超时时长为30分钟，那么可以设置该值为10分钟。
     */
    @Value("${simple-scheduler.task-reset-period:600000}")
    private int taskResetPeriod;

    /**
     * 心跳间隔，默认值10，单位秒。
     * 与性能无关
     * 筛选任务的高级策略需要使用该项。
     */
    @Value("${simple-scheduler.heart-beat-interval:10}")
    private int heartBeatInterval;

    /**
     * 任务表的名字，用户可自定义
     */
    @Value("${simple-scheduler.task-table:simple_scheduler_task}")
    private String taskTable;

    /**
     * 应用节点表的名字，用户可自定义
     */
    @Value("${simple-scheduler.node-table:simple_scheduler_node}")
    private String nodeTable;

    /**
     * 已完成的任务在任务表中存在的时长，单位天。
     * 超过指定时长的已完成状态的任务会被清理线程删除。
     */
    @Value("${simple-scheduler.clean.finished-task-exist-duration:0}")
    private int finishedTaskExistDuration;

    /**
     * 清理任务线程的起始执行时间
     */
    @Value("${simple-scheduler.clean.start-time:20:00:00}")
    private String cleanStartTime;

    /**
     * 清理任务线程的执行截至时间
     */
    @Value("${simple-scheduler.clean.stop-time:23:00:00}")
    private String cleanStopTime;

    @Bean(name = "SimpleSchedulerDataSource")
    @ConfigurationProperties(prefix = "simple-scheduler.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "SimpleSchedulerJdbcTemplate")
    public JdbcTemplate jdbcTemplate(@Qualifier("SimpleSchedulerDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}
